package com.four.order.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.four.common.utils.R;
import com.four.common.vo.CommodityTo;
import com.four.common.vo.UserTo;
import com.four.order.config.PaymentConfig;
import com.four.order.dao.PaymentDao;
import com.four.order.dao.ShoppingDao;
import com.four.order.entity.OrPayment;
import com.four.order.entity.OrShopping;
import com.four.order.feign.HospitalFeign;
import com.four.order.feign.SeckillFeign;
import com.four.order.service.PayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @Author: hxw
 * @Date: 2022/1/17 22:21
 */
@Service
public class PayServiceImpl implements PayService {
    @Autowired
    private ShoppingDao shoppingDao;
    @Autowired
    private SeckillFeign seckillFeign;
    @Autowired
    private HospitalFeign hospitalFeign;
    @Autowired
    private PaymentDao paymentDao;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private StringRedisTemplate redisTemplate;

    /**
     * 支付
     *
     * @param orId
     * @param token
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public String toPay(Integer orId, String token) {

//        try {

            //查询订单信息
            OrShopping byId = shoppingDao.getById(orId);
            //查询商品是否存在
            BoundHashOperations<String, String, String> map = redisTemplate.boundHashOps("four:seckill:list:seckStatus:1:");
            String s1 = map.get(byId.getComId());
            System.out.println(s1);
            CommodityTo byCommId = null;
            List<String> values = map.values();
            if (!CollectionUtils.isEmpty(values)) {
                for (String value : values) {
                    byCommId = JSON.parseObject(value, new TypeReference<CommodityTo>() {
                    });
                    if (byCommId.getComId().equals(byId.getComId())) {
                        break;
                    }
                }
            }
            if (byCommId == null) {
                return "该商品不存在或者已被秒杀";
            }
            //查询用户
            String s = redisTemplate.opsForValue().get(token);
            if (s == null) {
                return "该用户没有登录";
            }
            UserTo userTo = JSON.parseObject(s, new TypeReference<UserTo>() {
            });
            UserTo user = hospitalFeign.getShowUser(userTo.getUserId());
            if (!(user.getUserTotalPayment().compareTo(byId.getOrPrice()) > -1)) {
                return "您的余额已不足";
            }
            //修改金额
            userTo.setUserTotalPayment(userTo.getUserTotalPayment().subtract(byId.getOrPrice()));
            R r = hospitalFeign.updateByPayment(userTo);
            String code = String.valueOf(r.get("code"));
            String stat = "0";
            if (stat.equals(code)) {
                //删除对应的秒杀商品
                map.delete(byId.getComId().toString());
                //修改秒杀的商品状态
                byCommId.setComSeckStatus(2);
                r = seckillFeign.updateByStatus(byCommId);
                code = String.valueOf(r.get("code"));
                if (!stat.equals(code)) {
                    return "秒杀失败";
                }
                //修改订单状态
                byId.setOrStatus(1);
                shoppingDao.updateByStatus(byId);

                //添加支付
                OrPayment orPayment = new OrPayment();
                orPayment.setPaymentId(UUID.randomUUID() + "");
                orPayment.setPayName("支付宝");
                orPayment.setPayOrId(byId.getOrId());
                orPayment.setPayUserId(byId.getUserId());
                orPayment.setPayUserName(byId.getUserName());
                orPayment.setPayComId(byId.getComId());
                orPayment.setPayCreateTime(new Date());
                orPayment.setPayPrice(byCommId.getComPrice());
                orPayment.setPaySumPrice(byCommId.getSeckPrice());
                paymentDao.addPayment(orPayment);
                return "支付成功";
            }
//            else {
                return "支付失败";
//            }
//            return pay(byId, byCommId);
//        } catch (AlipayApiException e) {
//            e.printStackTrace();
//        }
//        return "支付成功";
    }

    /**
     * 支付
     *
     * @param byId
     * @param byCommId
     * @return
     */
    private String pay(OrShopping byId, CommodityTo byCommId) throws AlipayApiException {
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(PaymentConfig.gatewayUrl, PaymentConfig.app_id, PaymentConfig.merchant_private_key, "json", PaymentConfig.charset, PaymentConfig.alipay_public_key, PaymentConfig.sign_type);

        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(PaymentConfig.return_url);
        alipayRequest.setNotifyUrl(PaymentConfig.notify_url);

        //todo 根据当前用户的订单 查出订单号 支付价格  等信息
        //商户订单号，商户网站订单系统中唯一订单号，必填
        String outTradeNo = byId.getOrderId();
        //付款金额，必填
        BigDecimal totalAmount = byCommId.getSeckPrice();
        //订单名称，必填
        String subject = byCommId.getComName();
        //商品描述，可空
        String body = byCommId.getComName();

        alipayRequest.setBizContent("{\"out_trade_no\":\"" + outTradeNo + "\","
                + "\"total_amount\":\"" + totalAmount + "\","
                + "\"subject\":\"" + subject + "\","
                + "\"body\":\"" + body + "\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
        //若想给BizContent增加其他可选请求参数，以增加自定义超时时间参数timeout_express来举例说明
        //alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
        //		+ "\"total_amount\":\""+ total_amount +"\","
        //		+ "\"subject\":\""+ subject +"\","
        //		+ "\"body\":\""+ body +"\","
        //		+ "\"timeout_express\":\"10m\","
        //		+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
        //请求参数可查阅【电脑网站支付的API文档-alipay.trade.page.pay-请求参数】章节

        //请求
        String result = alipayClient.pageExecute(alipayRequest).getBody();
        //输出out.println(result);
        // 把字符串返回给浏览器 他就会自动跳转到支付宝页面
        return result;
    }

}
